home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / sre_parse.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  20KB  |  800 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Internal support module for sre'''
  5. import sys
  6. from sre_constants import *
  7.  
  8. def set(seq):
  9.     s = { }
  10.     for elem in seq:
  11.         s[elem] = 1
  12.     
  13.     return s
  14.  
  15. SPECIAL_CHARS = '.\\[{()*+?^$|'
  16. REPEAT_CHARS = '*+?{'
  17. DIGITS = set('0123456789')
  18. OCTDIGITS = set('01234567')
  19. HEXDIGITS = set('0123456789abcdefABCDEF')
  20. WHITESPACE = set(' \t\n\r\x0b\x0c')
  21. ESCAPES = {
  22.     '\\a': (LITERAL, ord('\x07')),
  23.     '\\b': (LITERAL, ord('\x08')),
  24.     '\\f': (LITERAL, ord('\x0c')),
  25.     '\\n': (LITERAL, ord('\n')),
  26.     '\\r': (LITERAL, ord('\r')),
  27.     '\\t': (LITERAL, ord('\t')),
  28.     '\\v': (LITERAL, ord('\x0b')),
  29.     '\\\\': (LITERAL, ord('\\')) }
  30. CATEGORIES = {
  31.     '\\A': (AT, AT_BEGINNING_STRING),
  32.     '\\b': (AT, AT_BOUNDARY),
  33.     '\\B': (AT, AT_NON_BOUNDARY),
  34.     '\\d': (IN, [
  35.         (CATEGORY, CATEGORY_DIGIT)]),
  36.     '\\D': (IN, [
  37.         (CATEGORY, CATEGORY_NOT_DIGIT)]),
  38.     '\\s': (IN, [
  39.         (CATEGORY, CATEGORY_SPACE)]),
  40.     '\\S': (IN, [
  41.         (CATEGORY, CATEGORY_NOT_SPACE)]),
  42.     '\\w': (IN, [
  43.         (CATEGORY, CATEGORY_WORD)]),
  44.     '\\W': (IN, [
  45.         (CATEGORY, CATEGORY_NOT_WORD)]),
  46.     '\\Z': (AT, AT_END_STRING) }
  47. FLAGS = {
  48.     'i': SRE_FLAG_IGNORECASE,
  49.     'L': SRE_FLAG_LOCALE,
  50.     'm': SRE_FLAG_MULTILINE,
  51.     's': SRE_FLAG_DOTALL,
  52.     'x': SRE_FLAG_VERBOSE,
  53.     't': SRE_FLAG_TEMPLATE,
  54.     'u': SRE_FLAG_UNICODE }
  55.  
  56. class Pattern:
  57.     
  58.     def __init__(self):
  59.         self.flags = 0
  60.         self.open = []
  61.         self.groups = 1
  62.         self.groupdict = { }
  63.  
  64.     
  65.     def opengroup(self, name = None):
  66.         gid = self.groups
  67.         self.groups = gid + 1
  68.         if name is not None:
  69.             ogid = self.groupdict.get(name, None)
  70.             if ogid is not None:
  71.                 raise error, 'redefinition of group name %s as group %d; was group %d' % (repr(name), gid, ogid)
  72.             
  73.             self.groupdict[name] = gid
  74.         
  75.         self.open.append(gid)
  76.         return gid
  77.  
  78.     
  79.     def closegroup(self, gid):
  80.         self.open.remove(gid)
  81.  
  82.     
  83.     def checkgroup(self, gid):
  84.         if gid < self.groups:
  85.             pass
  86.         return gid not in self.open
  87.  
  88.  
  89.  
  90. class SubPattern:
  91.     
  92.     def __init__(self, pattern, data = None):
  93.         self.pattern = pattern
  94.         if data is None:
  95.             data = []
  96.         
  97.         self.data = data
  98.         self.width = None
  99.  
  100.     
  101.     def dump(self, level = 0):
  102.         nl = 1
  103.         seqtypes = (type(()), type([]))
  104.         for op, av in self.data:
  105.             print level * '  ' + op,
  106.             nl = 0
  107.             if op == 'in':
  108.                 print 
  109.                 nl = 1
  110.                 for op, a in av:
  111.                     print (level + 1) * '  ' + op, a
  112.                 
  113.             elif op == 'branch':
  114.                 print 
  115.                 nl = 1
  116.                 i = 0
  117.                 for a in av[1]:
  118.                     if i > 0:
  119.                         print level * '  ' + 'or'
  120.                     
  121.                     a.dump(level + 1)
  122.                     nl = 1
  123.                     i = i + 1
  124.                 
  125.             elif type(av) in seqtypes:
  126.                 for a in av:
  127.                     if isinstance(a, SubPattern):
  128.                         if not nl:
  129.                             print 
  130.                         
  131.                         a.dump(level + 1)
  132.                         nl = 1
  133.                         continue
  134.                     print a,
  135.                     nl = 0
  136.                 
  137.             else:
  138.                 print av,
  139.                 nl = 0
  140.             if not nl:
  141.                 print 
  142.                 continue
  143.         
  144.  
  145.     
  146.     def __repr__(self):
  147.         return repr(self.data)
  148.  
  149.     
  150.     def __len__(self):
  151.         return len(self.data)
  152.  
  153.     
  154.     def __delitem__(self, index):
  155.         del self.data[index]
  156.  
  157.     
  158.     def __getitem__(self, index):
  159.         return self.data[index]
  160.  
  161.     
  162.     def __setitem__(self, index, code):
  163.         self.data[index] = code
  164.  
  165.     
  166.     def __getslice__(self, start, stop):
  167.         return SubPattern(self.pattern, self.data[start:stop])
  168.  
  169.     
  170.     def insert(self, index, code):
  171.         self.data.insert(index, code)
  172.  
  173.     
  174.     def append(self, code):
  175.         self.data.append(code)
  176.  
  177.     
  178.     def getwidth(self):
  179.         if self.width:
  180.             return self.width
  181.         
  182.         lo = hi = 0x0L
  183.         UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY)
  184.         REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
  185.         for op, av in self.data:
  186.             if op is BRANCH:
  187.                 i = sys.maxint
  188.                 j = 0
  189.                 for av in av[1]:
  190.                     (l, h) = av.getwidth()
  191.                     i = min(i, l)
  192.                     j = max(j, h)
  193.                 
  194.                 lo = lo + i
  195.                 hi = hi + j
  196.                 continue
  197.             if op is CALL:
  198.                 (i, j) = av.getwidth()
  199.                 lo = lo + i
  200.                 hi = hi + j
  201.                 continue
  202.             if op is SUBPATTERN:
  203.                 (i, j) = av[1].getwidth()
  204.                 lo = lo + i
  205.                 hi = hi + j
  206.                 continue
  207.             if op in REPEATCODES:
  208.                 (i, j) = av[2].getwidth()
  209.                 lo = lo + long(i) * av[0]
  210.                 hi = hi + long(j) * av[1]
  211.                 continue
  212.             if op in UNITCODES:
  213.                 lo = lo + 1
  214.                 hi = hi + 1
  215.                 continue
  216.             if op == SUCCESS:
  217.                 break
  218.                 continue
  219.         
  220.         self.width = (int(min(lo, sys.maxint)), int(min(hi, sys.maxint)))
  221.         return self.width
  222.  
  223.  
  224.  
  225. class Tokenizer:
  226.     
  227.     def __init__(self, string):
  228.         self.string = string
  229.         self.index = 0
  230.         self._Tokenizer__next()
  231.  
  232.     
  233.     def __next(self):
  234.         if self.index >= len(self.string):
  235.             self.next = None
  236.             return None
  237.         
  238.         char = self.string[self.index]
  239.         if char[0] == '\\':
  240.             
  241.             try:
  242.                 c = self.string[self.index + 1]
  243.             except IndexError:
  244.                 raise error, 'bogus escape (end of line)'
  245.  
  246.             char = char + c
  247.         
  248.         self.index = self.index + len(char)
  249.         self.next = char
  250.  
  251.     
  252.     def match(self, char, skip = 1):
  253.         if char == self.next:
  254.             if skip:
  255.                 self._Tokenizer__next()
  256.             
  257.             return 1
  258.         
  259.         return 0
  260.  
  261.     
  262.     def get(self):
  263.         this = self.next
  264.         self._Tokenizer__next()
  265.         return this
  266.  
  267.     
  268.     def tell(self):
  269.         return (self.index, self.next)
  270.  
  271.     
  272.     def seek(self, index):
  273.         (self.index, self.next) = index
  274.  
  275.  
  276.  
  277. def isident(char):
  278.     return None if char <= char else None if char <= char else char == '_'
  279.  
  280.  
  281. def isdigit(char):
  282.     return None if char <= char else char <= '9'
  283.  
  284.  
  285. def isname(name):
  286.     if not isident(name[0]):
  287.         return False
  288.     
  289.     for char in name[1:]:
  290.         if not isident(char) and not isdigit(char):
  291.             return False
  292.             continue
  293.     
  294.     return True
  295.  
  296.  
  297. def _class_escape(source, escape):
  298.     code = ESCAPES.get(escape)
  299.     if code:
  300.         return code
  301.     
  302.     code = CATEGORIES.get(escape)
  303.     if code:
  304.         return code
  305.     
  306.     
  307.     try:
  308.         c = escape[1:2]
  309.         if c == 'x':
  310.             while source.next in HEXDIGITS and len(escape) < 4:
  311.                 escape = escape + source.get()
  312.             escape = escape[2:]
  313.             if len(escape) != 2:
  314.                 raise error, 'bogus escape: %s' % repr('\\' + escape)
  315.             
  316.             return (LITERAL, int(escape, 16) & 255)
  317.         elif c in OCTDIGITS:
  318.             while source.next in OCTDIGITS and len(escape) < 4:
  319.                 escape = escape + source.get()
  320.             escape = escape[1:]
  321.             return (LITERAL, int(escape, 8) & 255)
  322.         elif c in DIGITS:
  323.             raise error, 'bogus escape: %s' % repr(escape)
  324.         
  325.         if len(escape) == 2:
  326.             return (LITERAL, ord(escape[1]))
  327.     except ValueError:
  328.         pass
  329.  
  330.     raise error, 'bogus escape: %s' % repr(escape)
  331.  
  332.  
  333. def _escape(source, escape, state):
  334.     code = CATEGORIES.get(escape)
  335.     if code:
  336.         return code
  337.     
  338.     code = ESCAPES.get(escape)
  339.     if code:
  340.         return code
  341.     
  342.     
  343.     try:
  344.         c = escape[1:2]
  345.         if c == 'x':
  346.             while source.next in HEXDIGITS and len(escape) < 4:
  347.                 escape = escape + source.get()
  348.             if len(escape) != 4:
  349.                 raise ValueError
  350.             
  351.             return (LITERAL, int(escape[2:], 16) & 255)
  352.         elif c == '0':
  353.             while source.next in OCTDIGITS and len(escape) < 4:
  354.                 escape = escape + source.get()
  355.             return (LITERAL, int(escape[1:], 8) & 255)
  356.         elif c in DIGITS:
  357.             if source.next in DIGITS:
  358.                 escape = escape + source.get()
  359.                 if escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS:
  360.                     escape = escape + source.get()
  361.                     return (LITERAL, int(escape[1:], 8) & 255)
  362.                 
  363.             
  364.             group = int(escape[1:])
  365.             if group < state.groups:
  366.                 if not state.checkgroup(group):
  367.                     raise error, 'cannot refer to open group'
  368.                 
  369.                 return (GROUPREF, group)
  370.             
  371.             raise ValueError
  372.         
  373.         if len(escape) == 2:
  374.             return (LITERAL, ord(escape[1]))
  375.     except ValueError:
  376.         pass
  377.  
  378.     raise error, 'bogus escape: %s' % repr(escape)
  379.  
  380.  
  381. def _parse_sub(source, state, nested = 1):
  382.     items = []
  383.     itemsappend = items.append
  384.     sourcematch = source.match
  385.     while None:
  386.         if sourcematch('|'):
  387.             continue
  388.         
  389.         if not nested:
  390.             break
  391.         
  392.         if not (source.next) or sourcematch(')', 0):
  393.             break
  394.             continue
  395.         raise error, 'pattern not properly closed'
  396.         continue
  397.         if len(items) == 1:
  398.             return items[0]
  399.         
  400.     subpattern = SubPattern(state)
  401.     subpatternappend = subpattern.append
  402.     while None:
  403.         prefix = None
  404.         for item in items:
  405.             if not item:
  406.                 break
  407.             
  408.             if prefix is None:
  409.                 prefix = item[0]
  410.                 continue
  411.             if item[0] != prefix:
  412.                 break
  413.                 continue
  414.         else:
  415.             for item in items:
  416.                 del item[0]
  417.             
  418.         break
  419.         continue
  420.         for item in items:
  421.             if len(item) != 1 or item[0][0] != LITERAL:
  422.                 break
  423.                 continue
  424.         else:
  425.             set = []
  426.             setappend = set.append
  427.             for item in items:
  428.                 setappend(item[0])
  429.             
  430.             return subpattern
  431.     subpattern.append((BRANCH, (None, items)))
  432.     return subpattern
  433.  
  434.  
  435. def _parse_sub_cond(source, state, condgroup):
  436.     item_yes = _parse(source, state)
  437.     if source.match('|'):
  438.         item_no = _parse(source, state)
  439.         if source.match('|'):
  440.             raise error, 'conditional backref with more than two branches'
  441.         
  442.     else:
  443.         item_no = None
  444.     if source.next and not source.match(')', 0):
  445.         raise error, 'pattern not properly closed'
  446.     
  447.     subpattern = SubPattern(state)
  448.     subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no)))
  449.     return subpattern
  450.  
  451. _PATTERNENDERS = set('|)')
  452. _ASSERTCHARS = set('=!<')
  453. _LOOKBEHINDASSERTCHARS = set('=!')
  454. _REPEATCODES = set([
  455.     MIN_REPEAT,
  456.     MAX_REPEAT])
  457.  
  458. def _parse(source, state):
  459.     subpattern = SubPattern(state)
  460.     subpatternappend = subpattern.append
  461.     sourceget = source.get
  462.     sourcematch = source.match
  463.     _len = len
  464.     PATTERNENDERS = _PATTERNENDERS
  465.     ASSERTCHARS = _ASSERTCHARS
  466.     LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS
  467.     REPEATCODES = _REPEATCODES
  468.     while source.next in PATTERNENDERS:
  469.         break
  470.     this = sourceget()
  471.     if this is None:
  472.         break
  473.     
  474.     if state.flags & SRE_FLAG_VERBOSE:
  475.         if this in WHITESPACE:
  476.             continue
  477.         
  478.         if this == '#':
  479.             while None:
  480.                 this = sourceget()
  481.                 if this in (None, '\n'):
  482.                     break
  483.                     continue
  484.                 continue
  485.                 continue
  486.         this == '#'
  487.     
  488.     None if this and this[0] not in SPECIAL_CHARS else sourcematch('?')
  489.     if this == '.':
  490.         subpatternappend((ANY, None))
  491.         continue
  492.     if this == '(':
  493.         group = 1
  494.         name = None
  495.         condgroup = None
  496.         if sourcematch('?'):
  497.             group = 0
  498.             if sourcematch('P'):
  499.                 if sourcematch('<'):
  500.                     name = ''
  501.                     while None:
  502.                         char = sourceget()
  503.                         if char is None:
  504.                             raise error, 'unterminated name'
  505.                         
  506.                         if char == '>':
  507.                             break
  508.                         
  509.                         name = name + char
  510.                         continue
  511.                         group = 1
  512.                         if not isname(name):
  513.                             raise error, 'bad character in group name'
  514.                         
  515.                 isname(name)
  516.                 if sourcematch('='):
  517.                     name = ''
  518.                     while None:
  519.                         char = sourceget()
  520.                         if char is None:
  521.                             raise error, 'unterminated name'
  522.                         
  523.                         if char == ')':
  524.                             break
  525.                         
  526.                         name = name + char
  527.                         continue
  528.                         if not isname(name):
  529.                             raise error, 'bad character in group name'
  530.                         
  531.                     gid = state.groupdict.get(name)
  532.                     if gid is None:
  533.                         raise error, 'unknown group name'
  534.                     
  535.                     subpatternappend((GROUPREF, gid))
  536.                     continue
  537.                 else:
  538.                     char = sourceget()
  539.                     if char is None:
  540.                         raise error, 'unexpected end of pattern'
  541.                     
  542.                     raise error, 'unknown specifier: ?P%s' % char
  543.             elif sourcematch(':'):
  544.                 group = 2
  545.             elif sourcematch('#'):
  546.                 while source.next is None or source.next == ')':
  547.                     break
  548.                 sourcematch('?')
  549.                 sourceget()
  550.                 continue
  551.                 if not sourcematch(')'):
  552.                     raise error, 'unbalanced parenthesis'
  553.                     continue
  554.                 continue
  555.             elif source.next in ASSERTCHARS:
  556.                 char = sourceget()
  557.                 dir = 1
  558.                 if char == '<':
  559.                     if source.next not in LOOKBEHINDASSERTCHARS:
  560.                         raise error, 'syntax error'
  561.                     
  562.                     dir = -1
  563.                     char = sourceget()
  564.                 
  565.                 p = _parse_sub(source, state)
  566.                 if not sourcematch(')'):
  567.                     raise error, 'unbalanced parenthesis'
  568.                 
  569.                 if char == '=':
  570.                     subpatternappend((ASSERT, (dir, p)))
  571.                     continue
  572.                 subpatternappend((ASSERT_NOT, (dir, p)))
  573.                 continue
  574.             elif sourcematch('('):
  575.                 condname = ''
  576.                 while None:
  577.                     char = sourceget()
  578.                     if char is None:
  579.                         raise error, 'unterminated name'
  580.                     
  581.                     if char == ')':
  582.                         break
  583.                     
  584.                     condname = condname + char
  585.                     continue
  586.                     group = 2
  587.                     if isname(condname):
  588.                         condgroup = state.groupdict.get(condname)
  589.                         if condgroup is None:
  590.                             raise error, 'unknown group name'
  591.                         
  592.                     else:
  593.                         
  594.                         try:
  595.                             condgroup = int(condname)
  596.                         except ValueError:
  597.                             raise error, 'bad character in group name'
  598.                         except:
  599.                             None<EXCEPTION MATCH>ValueError
  600.                         
  601.  
  602.                         None<EXCEPTION MATCH>ValueError
  603.                         if source.next not in FLAGS:
  604.                             raise error, 'unexpected end of pattern'
  605.                         
  606.             while source.next in FLAGS:
  607.                 state.flags = state.flags | FLAGS[sourceget()]
  608.         
  609.         if group:
  610.             if group == 2:
  611.                 group = None
  612.             else:
  613.                 group = state.opengroup(name)
  614.             if condgroup:
  615.                 p = _parse_sub_cond(source, state, condgroup)
  616.             else:
  617.                 p = _parse_sub(source, state)
  618.             if not sourcematch(')'):
  619.                 raise error, 'unbalanced parenthesis'
  620.             
  621.             if group is not None:
  622.                 state.closegroup(group)
  623.             
  624.             subpatternappend((SUBPATTERN, (group, p)))
  625.         else:
  626.             while None:
  627.                 char = sourceget()
  628.                 if char is None:
  629.                     raise error, 'unexpected end of pattern'
  630.                 
  631.                 if char == ')':
  632.                     break
  633.                 
  634.                 raise error, 'unknown extension'
  635.                 continue
  636.                 continue
  637.                 if this == '^':
  638.                     subpatternappend((AT, AT_BEGINNING))
  639.                     continue
  640.                 if this == '$':
  641.                     subpattern.append((AT, AT_END))
  642.                     continue
  643.                 if this and this[0] == '\\':
  644.                     code = _escape(source, this, state)
  645.                     subpatternappend(code)
  646.                     continue
  647.                 raise error, 'parser error'
  648.                 continue
  649.                 return subpattern
  650.  
  651.  
  652. def parse(str, flags = 0, pattern = None):
  653.     source = Tokenizer(str)
  654.     if pattern is None:
  655.         pattern = Pattern()
  656.     
  657.     pattern.flags = flags
  658.     pattern.str = str
  659.     p = _parse_sub(source, pattern, 0)
  660.     tail = source.get()
  661.     if tail == ')':
  662.         raise error, 'unbalanced parenthesis'
  663.     elif tail:
  664.         raise error, 'bogus characters at end of regular expression'
  665.     
  666.     if flags & SRE_FLAG_DEBUG:
  667.         p.dump()
  668.     
  669.     if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
  670.         return parse(str, p.pattern.flags)
  671.     
  672.     return p
  673.  
  674.  
  675. def parse_template(source, pattern):
  676.     s = Tokenizer(source)
  677.     sget = s.get
  678.     p = []
  679.     a = p.append
  680.     
  681.     def literal(literal, p = p, pappend = a):
  682.         if p and p[-1][0] is LITERAL:
  683.             p[-1] = (LITERAL, p[-1][1] + literal)
  684.         else:
  685.             pappend((LITERAL, literal))
  686.  
  687.     sep = source[:0]
  688.     if type(sep) is type(''):
  689.         makechar = chr
  690.     else:
  691.         makechar = unichr
  692.     while None:
  693.         this = sget()
  694.         if this is None:
  695.             break
  696.         
  697.         if this and this[0] == '\\':
  698.             c = this[1:2]
  699.             if c == 'g':
  700.                 name = ''
  701.                 if s.match('<'):
  702.                     while None:
  703.                         char = sget()
  704.                         if char is None:
  705.                             raise error, 'unterminated group name'
  706.                         
  707.                         if char == '>':
  708.                             break
  709.                         
  710.                         name = name + char
  711.                         continue
  712.                 s.match('<')
  713.                 if not name:
  714.                     raise error, 'bad group name'
  715.                 
  716.                 
  717.                 try:
  718.                     index = int(name)
  719.                     if index < 0:
  720.                         raise error, 'negative group number'
  721.                 except ValueError:
  722.                     if not isname(name):
  723.                         raise error, 'bad character in group name'
  724.                     
  725.                     
  726.                     try:
  727.                         index = pattern.groupindex[name]
  728.                     except KeyError:
  729.                         raise IndexError, 'unknown group name'
  730.                     except:
  731.                         None<EXCEPTION MATCH>KeyError
  732.                     
  733.  
  734.                     None<EXCEPTION MATCH>KeyError
  735.  
  736.                 a((MARK, index))
  737.             elif c == '0':
  738.                 if s.next in OCTDIGITS:
  739.                     this = this + sget()
  740.                     if s.next in OCTDIGITS:
  741.                         this = this + sget()
  742.                     
  743.                 
  744.                 literal(makechar(int(this[1:], 8) & 255))
  745.             elif c in DIGITS:
  746.                 isoctal = False
  747.                 if s.next in DIGITS:
  748.                     this = this + sget()
  749.                     if c in OCTDIGITS and this[2] in OCTDIGITS and s.next in OCTDIGITS:
  750.                         this = this + sget()
  751.                         isoctal = True
  752.                         literal(makechar(int(this[1:], 8) & 255))
  753.                     
  754.                 
  755.                 if not isoctal:
  756.                     a((MARK, int(this[1:])))
  757.                 
  758.             else:
  759.                 
  760.                 try:
  761.                     this = makechar(ESCAPES[this][1])
  762.                 except KeyError:
  763.                     pass
  764.  
  765.                 literal(this)
  766.         literal(this)
  767.         continue
  768.         i = 0
  769.         groups = []
  770.         groupsappend = groups.append
  771.         literals = [
  772.             None] * len(p)
  773.         for c, s in p:
  774.             if c is MARK:
  775.                 groupsappend((i, s))
  776.             else:
  777.                 literals[i] = s
  778.             i = i + 1
  779.         
  780.     return (groups, literals)
  781.  
  782.  
  783. def expand_template(template, match):
  784.     g = match.group
  785.     sep = match.string[:0]
  786.     (groups, literals) = template
  787.     literals = literals[:]
  788.     
  789.     try:
  790.         for index, group in groups:
  791.             literals[index] = s = g(group)
  792.             if s is None:
  793.                 raise error, 'unmatched group'
  794.                 continue
  795.     except IndexError:
  796.         raise error, 'invalid group reference'
  797.  
  798.     return sep.join(literals)
  799.  
  800.